﻿using System;
using System.Data;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using Marbles.Core.Connectors;
using Marbles.Core.Authentication;
using Marbles.Core.Encryption;
using Marbles.Core.Content.Sites;

namespace Marbles.Core.Authentication.Generic
{
    /// <summary>
    /// Generic Database Authentication Provider
    /// </summary>
    public class GenericProvider : AuthenticationProvider
    {
        public override string Provider { get { return "Generic"; } }
        public override bool RequiresPassword { get { return true; } }

        /// <summary>
        /// Authenticates a given user on the selected Authentication Provider
        /// </summary>
        /// <param name="identity">Username to authenticate</param>
        /// <param name="password">Password</param>
        /// <returns>True if Successful.</returns>
        public override bool Login(string identity, string password)
        {
            DataConnection dbc = new DataConnection();
            Command cmd = new Command("SELECT username, password, siteid FROM users WHERE username = @username AND siteid = @siteid AND enabled = 1");
            SiteDefinition web = SiteDefinition.GetCurrent();            
            cmd.AddParameter("@username", identity);
            cmd.AddParameter("@siteid", web.SiteId);
            DataTable dt = dbc.FetchDataTable(cmd);

            if (dt.Rows.Count > 0)
            {                
                string password1 = EncryptionProvider.Decode1(dt.Rows[0]["password"].ToString(), EncryptionProviderType.TripleDES);
                string siteid = dt.Rows[0]["siteid"].ToString();
                
                if (password == password1)
                {
                    
                    cmd = new Command("UPDATE users SET lastlogin = @lastlogin WHERE username = @username AND siteid = @siteid");
                    cmd.AddParameter("@username", identity);
                    cmd.AddParameter("@lastlogin", DateTime.Now);
                    cmd.AddParameter("@siteid", siteid);
                    dbc.ExecuteCommand(cmd);

                    IdentityToken token = new IdentityToken(dt);
                    SetCurrentToken(token);
                    return true;
                }

            }

            return false;
        }

        /// <summary>
        /// Retrieves the User token for the Authenticated User
        /// </summary>
        /// <param name="identity">Username of account</param>
        /// <param name="password">Password of account</param>
        /// <returns>IToken Containing User Information</returns>
        public override IToken GetToken(string identity, string password)
        {
            DataConnection dbc = new DataConnection();
            Command cmd = new Command("SELECT username, password, siteid FROM users WHERE username = @username AND siteid = @siteid AND enabled = 1");
            SiteDefinition web = SiteDefinition.GetCurrent();
            cmd.AddParameter("@username", identity);
            cmd.AddParameter("@siteid", web.SiteId);
            DataTable dt = dbc.FetchDataTable(cmd);

            if (dt.Rows.Count > 0)
            {
                string password1 = EncryptionProvider.Decode1(dt.Rows[0]["password"].ToString(), EncryptionProviderType.TripleDES);
                string siteid = dt.Rows[0]["siteid"].ToString();
                if (password == password1)
                {
                    cmd = new Command("UPDATE users SET lastlogin = @lastlogin WHERE username = @username AND siteid = @siteid");
                    cmd.AddParameter("@username", identity);
                    cmd.AddParameter("@lastlogin", DateTime.Now);
                    cmd.AddParameter("@siteid", siteid);
                    dbc.ExecuteCommand(cmd);

                    IdentityToken token = new IdentityToken(dt);
                    return token;
                }

            }

            return null;
        }

        /// <summary>
        /// Authenticates the current user.
        /// </summary>
        /// <returns>Returns a valid token if Successful, else returns null</returns>
        public override IToken Authenticate()
        {
            IdentityToken token = GetCurrentToken() as IdentityToken;

            if (token == null) { return new IdentityToken(); }

            return token;
        }

    }
}
